package cn.huhaoran.yaoyaolingxian.util;

import cn.huhaoran.yaoyaolingxian.ui.CustomTreeTableImpl.GitBranchNode;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.commands.Git;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.ui.UIUtil;
import git4idea.GitLocalBranch;
import git4idea.GitRemoteBranch;
import git4idea.commands.GitCommand;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitLineHandler;
import git4idea.config.GitExecutableManager;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import com.intellij.vcs.log.Hash;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author huhaoran
 * @description: 遥遥领先工具类
 * @date 2024/7/14
 */
public class YaoYaoLingXianUtils {
    /**
     * generatePageFile 生成页面文件
     *
     * @param e    com.intellij.openapi.actionSystem.AnActionEvent
     * @param data java.util.HashMap<java.lang.String,java.lang.Object>
     * @param cl   java.lang.ClassLoader
     * @return void
     * @author huhaoran
     * @date 2024/8/11
     */
    public static void generatePageFile(AnActionEvent e, HashMap<String, Object> data, ClassLoader cl) {
       /* ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(cl);*/
        String filePath = (String) data.remove("filePath");
        String jsonPath = (String) data.remove("jsonPath");
        String enumPath = (String) data.remove("enumPath");
        String pageName = (String) data.get("pageName");
        String pageNameCN = (String) data.get("pageNameCN");
        String enumIndex = (String) data.get("enumIndex");
        VelocityContext context = new VelocityContext();
        data.forEach(context::put);

        String templatePageName = "${pageName}Page.ets";
        String tagePageName = templatePageName.replace("${pageName}", pageName);
        String pagePath = filePath + File.separator + tagePageName;

        String templateViewModelName = "${pageName}ViewModel.ets";
        String tageViewModelName = templateViewModelName.replace("${pageName}", pageName);
        String ViewModelPath = filePath + File.separator + tageViewModelName;
        // 文件生成
        String s = writeFile("vm/v1/${pageName}Page.ets.vm", context, pagePath, cl);
        String s2 = writeFile("vm/v1/${pageName}ViewModel.ets.vm", context, ViewModelPath, cl);
        // 写入json和枚举
        // 获取src路径
        String srcPath = pagePath.substring(pagePath.indexOf("src"));
        srcPath = srcPath.replace("\\", "/");
        String jsonTemplate = ",\n" +
                "    {\n" +
                "      \"name\": \"${pageName}Page\",\n" +
                "      \"pageSourceFile\": \"${srcPath}\",\n" +
                "      \"buildFunction\": \"${pageName}PageBuilder\",\n" +
                "      \"data\": {\n" +
                "        \"description\": \"${pageNameCN}\"\n" +
                "      }\n" +
                "    }";
        String enumTemplate = ",\n" +
                "  // ${pageNameCN}\n" +
                "  ${pageName}Page = \"${pageName}Page\"";
        jsonTemplate = jsonTemplate.replace("${pageName}", pageName);
        jsonTemplate = jsonTemplate.replace("${srcPath}", srcPath);
        jsonTemplate = jsonTemplate.replace("${pageNameCN}", pageNameCN);

        enumTemplate = enumTemplate.replace("${pageName}", pageName);
        enumTemplate = enumTemplate.replace("${pageNameCN}", pageNameCN);

        // 读取 jsonPath 文件，并从后向前查找第二个"}"字符，并把jsonTemplate插入该字符后面，再保存文件
        try {
            // 读取json文件内容
            String jsonContent = new String(Files.readAllBytes(Paths.get(jsonPath)), "UTF-8");
            // 从后向前查找第二个 "}" 字符
            int firstBraceIndex = jsonContent.lastIndexOf("}");
            int secondBraceIndex = jsonContent.lastIndexOf("}", firstBraceIndex - 1);
            if (secondBraceIndex != -1) {
                // 在第二个 "}" 字符后面插入 jsonTemplate
                StringBuilder modifiedContent = new StringBuilder(jsonContent);
                modifiedContent.insert(secondBraceIndex + 1, jsonTemplate);
                // 保存修改后的内容到文件
                Files.write(Paths.get(jsonPath), modifiedContent.toString().getBytes("UTF-8"), StandardOpenOption.WRITE);
                System.out.println("JSON template has been inserted successfully.");
            } else {
                System.out.println("Could not find the second closing brace '}' in the file.");
            }
            // 读取枚举文件内容
            String enumContent = new String(Files.readAllBytes(Paths.get(enumPath)), "UTF-8");
            // 将enumIndex字符串转换成整数型

            int i = Integer.parseInt(enumIndex) - 1;
            int huanhangIndex = enumContent.lastIndexOf("\"", i);
            int huanhangIndexs = enumContent.lastIndexOf("'", i);
            huanhangIndex = huanhangIndex > huanhangIndexs ? huanhangIndex : huanhangIndexs;

            StringBuilder modifiedContent2 = new StringBuilder(enumContent);
            modifiedContent2.insert(huanhangIndex + 1, enumTemplate);
            // 保存修改后的内容到文件
            Files.write(Paths.get(enumPath), modifiedContent2.toString().getBytes("UTF-8"), StandardOpenOption.WRITE);
        } catch (IOException ex) {
            Notifications.Bus.notify(new Notification("Print", "写入json或枚举时出现错误" + ex.getMessage(),
                    s + "\n" + s2, NotificationType.WARNING), e.getProject());
        }

        Notifications.Bus.notify(new Notification("Print", "生成结果",
                s + "\n" + s2, NotificationType.INFORMATION), e.getProject());
/*
        File file = new File(filePath);
        try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8)) {
            if (!file.exists() && !file.mkdirs()) {
                throw new RuntimeException("将要生成的文件已经存在或者是一个目录！");
            }
            VelocityEngine velocityEngine = new VelocityEngine();
            velocityEngine.setProperty(Velocity.RESOURCE_LOADER, "classpath");
            velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
            velocityEngine.setProperty("output.encoding", "UTF-8");
            velocityEngine.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
            velocityEngine.init();
            Template tpl = velocityEngine.getTemplate("vm/v1/" + templateName + ".vm", StandardCharsets.UTF_8.name());
            BufferedWriter sw = new BufferedWriter(out);
            tpl.merge(context, sw);
            sw.flush();
            sw.close();
        } catch (Exception error) {
            Notifications.Bus.notify(new Notification("Print", "生成代码时发生错误！",
                    "错误信息：" + error.getMessage(), NotificationType.INFORMATION), e.getProject());
        }
        Thread.currentThread().setContextClassLoader(oldContextClassLoader);*/
    }

    /**
     * writeFile 通过模板输出到文件
     *
     * @param templateFilePath java.lang.String 模板文件路径+名称
     * @param velocityContext  org.apache.velocity.VelocityContext 模板上下文对象
     * @param targetPath       java.lang.String 输出目标文件路径
     * @param cl               java.lang.ClassLoader 类加载器
     * @return void
     * @author huhaoran
     * @date 2024/7/15
     */
    private static String writeFile(String templateFilePath, VelocityContext velocityContext, String targetPath, ClassLoader cl) {
        ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(cl);
        OutputStreamWriter out = null;
        BufferedWriter sw = null;
        try {
            File file = new File(targetPath);
            if (file.exists()) {
                throw new RuntimeException("将要生成的文件已经存在！");
            }
            // 确保父目录存在
            File parentDir = file.getParentFile();
            if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
                throw new RuntimeException("创建目标文件的父目录失败！");
            }
            // 创建文件
            if (!file.createNewFile()) {
                throw new RuntimeException("将要生成的文件已经存在或者是一个目录！");
            }
            out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            VelocityEngine velocityEngine = new VelocityEngine();
            velocityEngine.setProperty(Velocity.RESOURCE_LOADER, "classpath");
            velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
            velocityEngine.setProperty("output.encoding", "UTF-8");
            velocityEngine.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
            velocityEngine.init();
            Template tpl = velocityEngine.getTemplate(templateFilePath, StandardCharsets.UTF_8.name());
            sw = new BufferedWriter(out);
            tpl.merge(velocityContext, sw);
            sw.flush();
        } catch (Exception error) {
            return "从模板" + templateFilePath + "生成文件" + targetPath + "的时候出现错误：" + error.getMessage();
        } finally {
            Thread.currentThread().setContextClassLoader(oldContextClassLoader);
            try {
                if (sw != null) {
                    sw.close();
                }
            } catch (IOException e) {
                return "关闭缓存区的时候发生错误：" + e.getMessage();
            }
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                return "关闭文件输出流的时候发生错误：" + e.getMessage();
            }
        }
        return "成功通过模板" + templateFilePath + "生成目标文件" + targetPath;
    }

    /**
     * areStringsEqual 比较两个字符串是否相同
     *
     * @param str1 java.lang.String
     * @param str2 java.lang.String
     * @return boolean
     * @author huhaoran
     * @date 2024/7/16
     */
    public static boolean areStringsEqual(String str1, String str2) {
        if (str1 == null && str2 == null) {
            return true;
        } else if (str1 != null && str2 != null) {
            return str1.equals(str2);
        } else {
            return false;
        }
    }

    /**
     * showBalloon 在指定组件上弹出一个消息框
     *
     * @param component javax.swing.JComponent
     * @param message   java.lang.String
     * @return void
     * @author huhaoran
     * @date 2024/7/17
     */
    public static void showMessgerOnBalloon(JComponent component, String message) {
        Balloon balloon = JBPopupFactory.getInstance()
                .createHtmlTextBalloonBuilder(message, null, new Color(255, 94, 94, 194), null)
                .setFadeoutTime(3000)
                .createBalloon();

        // 显示在组件上方
        balloon.show(RelativePoint.getSouthOf(component), Balloon.Position.atLeft);
    }

    /**
     * parseFileContent 将文件内容转换为 Map<String, List<String>>
     *
     * @param filePath java.lang.String
     * @return java.util.Map<java.lang.String, java.util.List < java.lang.String>>
     * @author huhaoran
     * @date 2024/8/11
     */
    public static Map<String, List<String>> parseFileContent(String filePath) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filePath)), "UTF-8");
        // 正则表达式匹配枚举类
        Pattern enumPattern = Pattern.compile(
                "export enum (\\w+)\\s*\\{(.*?)\\}",
                Pattern.DOTALL
        );
        // 正则表达式匹配枚举值
        Pattern valuePattern = Pattern.compile(
                "(\\w+)\\s*=\\s*\".*?\""
        );
        Map<String, List<String>> result = new HashMap<>();
        Matcher enumMatcher = enumPattern.matcher(content);
        while (enumMatcher.find()) {
            String enumName = enumMatcher.group(1);
            String enumBody = enumMatcher.group(2);
            List<String> enumValues = new ArrayList<>();
            // 查找结束大括号的位置
            int endBracePos = content.indexOf('}', enumMatcher.end() - 1);
            enumValues.add(String.valueOf(endBracePos));
            Matcher valueMatcher = valuePattern.matcher(enumBody);
            while (valueMatcher.find()) {
                enumValues.add(valueMatcher.group(1));
            }
            result.put(enumName, enumValues);
        }
        return result;
    }

    /**
     * parseFileContentV2 将文件内容转换为 Map<String, List<String>>
     *
     * @param filePath java.lang.String
     * @return java.util.Map<java.lang.String, java.util.List < java.lang.String>>
     * @author huhaoran
     * @date 2024/8/11
     */
    public static Map<String, List<String>> parseFileContentV2(String filePath) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filePath)), "UTF-8");

        // 正则表达式匹配注释和枚举类
        Pattern enumPattern = Pattern.compile(
                "(?:(?:/\\*\\*.*?\\*/)|(?://.*?\\n))*\\s*export enum (\\w+)\\s*\\{(.*?)\\}",
                Pattern.DOTALL | Pattern.MULTILINE
        );

        // 正则表达式匹配枚举值
        Pattern valuePattern = Pattern.compile(
                "(\\w+)\\s*=\\s*\".*?\""
        );

        Map<String, List<String>> result = new HashMap<>();
        Matcher enumMatcher = enumPattern.matcher(content);

        while (enumMatcher.find()) {
            String enumBlock = content.substring(0, enumMatcher.start());
            String enumName = enumMatcher.group(1);
            String enumBody = enumMatcher.group(2);
            List<String> enumValues = new ArrayList<>();

            // 查找结束大括号的位置
            int endBracePos = content.indexOf('}', enumMatcher.end());
            enumValues.add(String.valueOf(endBracePos));

            Matcher valueMatcher = valuePattern.matcher(enumBody);
            while (valueMatcher.find()) {
                enumValues.add(valueMatcher.group(1));
            }

            // 提取注释
            String comment = extractComment(enumBlock);
            String key = enumName + "//" + comment;
            result.put(key, enumValues);
        }

        return result;
    }

    /**
     * extractComment 提取注释内容
     *
     * @param enumBlock java.lang.String
     * @return java.lang.String
     * @author huhaoran
     * @date 2024/8/11
     */
    private static String extractComment(String enumBlock) {
        Pattern commentPattern = Pattern.compile("(?:/\\*\\*(.*?)\\*/)|(?://(.*?))\\n", Pattern.DOTALL | Pattern.MULTILINE);
        Matcher commentMatcher = commentPattern.matcher(enumBlock);
        StringBuilder comments = new StringBuilder();
        while (commentMatcher.find()) {
            if (commentMatcher.group(1) != null) {
                comments.append(commentMatcher.group(1).trim()).append(" ");
            } else if (commentMatcher.group(2) != null) {
                comments.append(commentMatcher.group(2).trim()).append(" ");
            }
        }
        return comments.toString().trim();
    }

    /**
     * getAllBranches 获取项目所有分支，远程+本地
     *
     * @param project com.intellij.openapi.project.Project
     * @return java.util.List<java.lang.String>
     * @author huhaoran
     * @date 2024/8/11
     */
    public static List<HashMap<String, String>> getAllBranches(Project project) {
        // 获取项目的 GitRepositoryManager 实例
        GitRepositoryManager repositoryManager = GitRepositoryManager.getInstance(project);

        // 获取项目中的所有 Git 仓库
        List<GitRepository> repositories = repositoryManager.getRepositories();

        // 创建结果列表
        List<HashMap<String, String>> branchList = new ArrayList<>();

        // 遍历每个仓库，收集分支和远程仓库信息
        for (GitRepository repo : repositories) {
            // 获取远程仓库的 URL
            Collection<GitRemote> remotes = repo.getRemotes();
            for (GitRemote remote : remotes) {
                HashMap<String, String> remoteInfo = new HashMap<>();
                remoteInfo.put("branchName", remote.getName());
                remoteInfo.put("originUrl", remote.getFirstUrl());
                // 远程仓库不需要 hash 值
                branchList.add(remoteInfo);
            }

            // 获取本地分支列表并收集信息
            Collection<GitLocalBranch> localBranches = repo.getBranches().getLocalBranches();
            for (GitLocalBranch localBranch : localBranches) {
                HashMap<String, String> branchInfo = new HashMap<>();
                branchInfo.put("branchName", localBranch.getName());
                branchInfo.put("branchHash", getBranchHash(repo, localBranch));
                branchInfo.put("originUrl", getRemoteUrlForBranch(repo, localBranch.getName()));
                branchList.add(branchInfo);
            }

            // 获取远程分支列表并收集信息
            Collection<GitRemoteBranch> remoteBranches = repo.getBranches().getRemoteBranches();
            for (GitRemoteBranch remoteBranch : remoteBranches) {
                HashMap<String, String> branchInfo = new HashMap<>();
                branchInfo.put("branchName", remoteBranch.getName());
                branchInfo.put("branchHash", getBranchHash(repo, remoteBranch));
                branchInfo.put("originUrl", remoteBranch.getRemote().getFirstUrl());
                branchList.add(branchInfo);
            }
        }

        return branchList;
    }

    // Helper 方法来获取本地分支的远程URL
    private static String getRemoteUrlForBranch(GitRepository repo, String branchName) {
        return repo.getBranchTrackInfos().stream()
                .filter(info -> info.getLocalBranch().getName().equals(branchName))
                .findFirst()
                .map(info -> info.getRemote().getFirstUrl())
                .orElse(null);
    }

    // Helper 方法来获取本地分支的最新提交哈希值
    private static String getBranchHash(@NotNull GitRepository repo, @NotNull GitLocalBranch localBranch) {
        Hash branchHash = repo.getBranches().getHash(localBranch);
        return branchHash != null ? branchHash.asString() : null;
    }

    // Helper 方法来获取远程分支的最新提交哈希值
    private static String getBranchHash(@NotNull GitRepository repo, @NotNull GitRemoteBranch remoteBranch) {
        Hash branchHash = repo.getBranches().getHash(remoteBranch);
        return branchHash != null ? branchHash.asString() : null;
    }

    /**
     * 将图标路径转换为 Image 对象
     *
     * @param iconPath 图标的路径，例如 "/icons/ic_public_file_filled.svg"
     * @param clazz    用于加载图标的类（通常是调用此方法的类）
     * @return Image 对象
     */
    public static Image loadIconAsImage(String iconPath, Class<?> clazz) {
        // 使用 IconLoader 加载 SVG 图标
        Icon myIcon = IconLoader.getIcon(iconPath, clazz);

        // 使用 UIUtil.createImage() 创建 BufferedImage
        BufferedImage image = UIUtil.createImage(
                myIcon.getIconWidth(),
                myIcon.getIconHeight(),
                BufferedImage.TYPE_INT_ARGB
        );

        Graphics2D g2d = image.createGraphics();
        myIcon.paintIcon(null, g2d, 0, 0);
        g2d.dispose();

        return image;
    }

    /**
     * getGitExecutablePath 获取项目git路径
     *
     * @param
     * @return java.lang.String
     * @author huhaoran
     * @date 2024/8/11
     */
    public static String getGitExecutablePath() {
        // 获取当前打开的项目
        Project project = ProjectManager.getInstance().getDefaultProject();

        // 使用 GitExecutableManager 获取 Git 的可执行文件路径
        return GitExecutableManager.getInstance().getPathToGit(project);
    }

    public static void gitBundleCreate(String[] args) {
        // 获取项目中的 Git 仓库
        // 获取当前打开的项目
        Project project = ProjectManager.getInstance().getDefaultProject();
        GitRepositoryManager repositoryManager = GitRepositoryManager.getInstance(project);
        List<GitRepository> repositories = repositoryManager.getRepositories();

        if (repositories.isEmpty()) {
            Messages.showErrorDialog(project, "No Git repository found in this project.", "Error");
            return;
        }
        // 获取第一个 Git 仓库（你可以根据需要遍历多个仓库）
        GitRepository repository = repositories.get(0);
        VirtualFile root = repository.getRoot(); // 获取仓库根目录

        // 使用 GitLineHandler 来执行 git bundle create
/*        GitLineHandler handler = new GitLineHandler(project, root, GitCommand.w);
        handler.addParameters("bundle", "create", bundlePath, branch);  // 添加 git bundle create 参数
        handler.setSilent(false);  // 设置为非静默模式，显示输出

        // 执行 Git 命令
        GitCommandResult result = Git.getInstance().runCommand(handler);

        // 检查结果并处理
        if (result.success()) {
            Messages.showInfoMessage(project, "Fetched branch " + branch + " from bundle " + bundlePath, "Success");
            repository.update();  // 更新本地 Git 仓库状态
        } else {
            Messages.showErrorDialog(project, "Failed to fetch from bundle: " + result.getErrorOutputAsJoinedString(), "Error");
        }*/
    }

    /**
     * createGitBundle 创建导出分支文件
     *
     * @param gitExecutable   java.lang.String
     * @param projectPath     java.lang.String
     * @param filePath        java.lang.String
     * @param branchName      java.lang.String
     * @param useUtf8Encoding boolean
     * @return void
     * @author huhaoran
     * @date 2024/8/12
     */
    public static void createGitBundle(String gitExecutable, String projectPath, String filePath, String branchName, boolean useUtf8Encoding) {
        try {
            // 对包含空格的路径进行引号处理
            gitExecutable = "\"" + gitExecutable + "\"";
            //projectPath = "\"" + projectPath + "\"";
            filePath = "\"" + filePath + "\"";

            String command = "git bundle create " + filePath + " " + branchName;
            List<String> fullCommand = new ArrayList<>();

            if (useUtf8Encoding) {
                command = convertToUTF8(command); // 将命令转换为 UTF-8
            }
            Project project = ProjectManager.getInstance().getDefaultProject();
       /*     TerminalView terminalView = TerminalView.getInstance(project);
            TerminalWidget terminalWidget = terminalView.createLocalShellWidget(null, null);

            terminalWidget.executeCommand(command);*/

            // 根据操作系统选择合适的终端命令
            if (isWindows()) {
                fullCommand.add("cmd.exe");
                fullCommand.add("/c");
                fullCommand.add("start");
                fullCommand.add("cmd.exe");
                fullCommand.add("/k");
                fullCommand.add((useUtf8Encoding ? "chcp 65001 && " : "") + command);
                // "cd /d " + projectPath + " && " +
            } else { //  if (isMac())
         /*   Notifications.Bus.notify(new Notification("Print", "调试信息",
                    "进入了mac逻辑", NotificationType.INFORMATION), getActiveProject());*/

           /* fullCommand.add("osascript");
            fullCommand.add("-e");
            fullCommand.add("tell application \"Terminal\" to do script \"cd '" + projectPath + "' && " + command + "\"");*/
                fullCommand.add("/bin/bash");
                fullCommand.add("-c");
                fullCommand.add(command);
            }

    /*    else {
            fullCommand.add("sh");
            fullCommand.add("-c");
            fullCommand.add("cd '" + projectPath + "' && " + command + "; exec bash");
        }*/


            Notifications.Bus.notify(new Notification("Print", "分支导出",
                    "执行导出命令:" + fullCommand, NotificationType.INFORMATION), getActiveProject());
            ProcessBuilder processBuilder = new ProcessBuilder(fullCommand);
            processBuilder.directory(new File(projectPath));
            processBuilder.start();
        } catch (Exception e) {
            System.err.println("Error executing command: " + e.getMessage());
            Notifications.Bus.notify(new Notification("Print", "调试信息",
                    "发生错误:" + e.getMessage(), NotificationType.ERROR), getActiveProject());
        }
    }

    private static String convertToUTF8(String text) {
        try {
            byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
            return new String(bytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return text; // 如果转换失败，返回原始文本
        }
    }

    private static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().contains("win");
    }

    private static boolean isMac() {
        return System.getProperty("os.name").toLowerCase().contains("mac");
    }


    /**
     * getBranchesFromBundle 通过git命令获取分支列表
     *
     * @param gitExecutable   java.lang.String
     * @param projectPath     java.lang.String
     * @param bundleFilePath  java.lang.String
     * @param useUtf8Encoding boolean
     * @return java.util.List<java.lang.String>
     * @author huhaoran
     * @date 2024/8/12
     */
    public static List<String> getBranchesFromBundle(String gitExecutable, String projectPath, String bundleFilePath, boolean useUtf8Encoding) {
        List<String> branches = new ArrayList<>();
        try {
            // 对包含空格的路径进行引号处理
            gitExecutable = "\"" + gitExecutable + "\"";
            //projectPath = "\"" + projectPath + "\"";
            bundleFilePath = "\"" + bundleFilePath + "\"";

            // 构建 git bundle list-heads 命令 gitExecutable +
            String command = "git bundle list-heads " + bundleFilePath;
            if (useUtf8Encoding) {
                command = convertToUTF8(command);
            }

            List<String> fullCommand = new ArrayList<>();
            if (isWindows()) {
                fullCommand.add("cmd.exe");
                fullCommand.add("/c");
                fullCommand.add((useUtf8Encoding ? "chcp 65001 && " : " ") + command);
            } else {
       /*         fullCommand.add("osascript");
                fullCommand.add("-e");
                fullCommand.add("tell application \"Terminal\" to do script \"cd '" + projectPath + "' && " + command + "\"");*/
                fullCommand.add("/bin/bash");
                fullCommand.add("-c");
                fullCommand.add(command);
            }
           /* else {
                fullCommand.add("sh");
                fullCommand.add("-c");
                fullCommand.add("cd '" + projectPath + "' && " + command + "; exec bash");
            }*/

            ProcessBuilder processBuilder = new ProcessBuilder(fullCommand);
            processBuilder.directory(new File(projectPath));
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();

            // 读取命令输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                branches.add(line);
            }

            process.waitFor();
        } catch (Exception e) {
            System.err.println("Error executing command: " + e);
        }

        return branches;
    }

    /**
     * getFetchByBundle 执行git Fetch命令
     *
     * @param gitPath          java.lang.String
     * @param projectPath      java.lang.String
     * @param selectedBranches java.util.List<cn.huhaoran.yaoyaolingxian.ui.CustomTreeTableImpl.GitBranchNode>
     * @param useUtf8Encoding  boolean
     * @return boolean
     * @author huhaoran
     * @date 2024/8/12
     */
    public static int getFetchByBundle(String gitPath, String projectPath, String bundleFilePath, List<GitBranchNode> selectedBranches, boolean useUtf8Encoding) {
            ArrayList<String> branches = new ArrayList<>();
            //GitBranchNode gitBranchNode = selectedBranches.get(0);
            if(selectedBranches.size()!=0){
                int i = 0;
                for (GitBranchNode branch : selectedBranches) {
                    try {
                        extracted(projectPath, bundleFilePath, useUtf8Encoding, branch);
                        i++;
                    } catch (IOException e) {
                        showMessage("导入分支"+branch.getBranchName()+"时发生错误：", e.getMessage(), NotificationType.ERROR);
                    }
                }
                return i;
            }else{
                return 0;
            }
            // 更新分支列表
          /*  Project project = getActiveProject();
            GitRepositoryManager repositoryManager = GitRepositoryManager.getInstance(project);
            List<GitRepository> repositories = repositoryManager.getRepositories();
            if (!repositories.isEmpty()) {
                GitRepository gitRepository = repositories.get(0);
                SwingUtilities.invokeLater(gitRepository::update);
                //gitRepository.update();
            }*/
    }

    private static void extracted(String projectPath, String bundleFilePath, boolean useUtf8Encoding, GitBranchNode gitBranchNode) throws IOException {
        // 对包含空格的路径进行引号处理
        //projectPath = "\"" + projectPath + "\"";
        bundleFilePath = "\"" + bundleFilePath + "\"";
        String command = "git fetch " + bundleFilePath + " " +
                gitBranchNode.getFullBranchName().trim() +
                ":" + gitBranchNode.getEditableName().trim();
        if (useUtf8Encoding) {
            command = convertToUTF8(command);
        }
        List<String> fullCommand = new ArrayList<>();
        // 根据操作系统选择合适的终端命令
        if (isWindows()) {
            fullCommand.add("cmd.exe");
            fullCommand.add("/c");
            fullCommand.add("start");
            fullCommand.add("cmd.exe");
            fullCommand.add("/k"); // "cd /d " + projectPath + " && "
            fullCommand.add((useUtf8Encoding ? "chcp 65001 && " : " ") + command);
        } else { // if (isMac())
            //fullCommand.add("osascript");
            //fullCommand.add("-e");
            //fullCommand.add("tell application \"Terminal\" to do script \"cd '" + projectPath + "' && " + command + "\"");
            fullCommand.add("/bin/bash");
            fullCommand.add("-c");
            fullCommand.add(command);
        }
        ProcessBuilder processBuilder = new ProcessBuilder(fullCommand);
        processBuilder.directory(new File(projectPath));
        processBuilder.start();
    }


    /**
     * gitFetchBundle 采用idea自带的git包执行fetch命令
     * @author huhaoran
     * @date 2024/8/30
     *
     * @param bundleFilePath java.lang.String
	 * @param selectedBranches java.util.List<cn.huhaoran.yaoyaolingxian.ui.CustomTreeTableImpl.GitBranchNode>
     * @return int
     */
    public static int gitFetchBundle(String bundleFilePath, List<GitBranchNode> selectedBranches) {
        bundleFilePath = "\"" + bundleFilePath + "\"";
        List<String> commandList = new ArrayList<String>();
        String finalBundleFilePath = bundleFilePath;
        // 拼装执行命令列表
        selectedBranches.forEach(gitBranchNode -> {
            commandList.add(finalBundleFilePath + " " +
                    gitBranchNode.getFullBranchName().trim() +
                    ":" + gitBranchNode.getEditableName().trim()
            );
        });
        // 获取项目中的 Git 仓库
        // 获取当前打开的项目
        Project project = getActiveProject();
        GitRepositoryManager repositoryManager = GitRepositoryManager.getInstance(project);
        List<GitRepository> repositories = repositoryManager.getRepositories();

        if (repositories.isEmpty()) {
            Messages.showErrorDialog(project, "No Git repository found in this project.", "Error");
            return 0;
        }
        // 获取第一个 Git 仓库（你可以根据需要遍历多个仓库）
        GitRepository repository = repositories.get(0);
        VirtualFile root = repository.getRoot(); // 获取仓库根目录

        // 使用 GitLineHandler 来执行 git bundle create
      /*  GitLineHandler handler = new GitLineHandler(project, root, GitCommand.FETCH);
        handler.addParameters(bundleFilePath, branch);  // 添加 git bundle create 参数
        handler.setSilent(false);  // 设置为非静默模式，显示输出*/

        AtomicInteger runSuccessNum = new AtomicInteger();

        // 批量处理所有选中分支
        commandList.forEach(command -> {
            // 使用 GitLineHandler 来执行 git bundle create
            GitLineHandler handler = new GitLineHandler(project, root, GitCommand.FETCH);
            handler.addParameters(command);  // 添加 git bundle create 参数
            handler.setSilent(false);  // 设置为非静默模式，显示输出
            // 执行 Git 命令
            Git instance = Git.getInstance();
            GitCommandResult result = instance.runCommand(handler);
            if(result.success()){
                runSuccessNum.getAndIncrement();
            }
        });
        repository.update();  // 更新本地 Git 仓库状态
        Messages.showInfoMessage(project, "分支导入情况", "总共["+commandList.size()+"]个选中分支，成功导入["+runSuccessNum.get()+"]个。");
   /*     // 执行 Git 命令
        GitCommandResult result = Git.getInstance().runCommand(handler);*/

        // 检查结果并处理
     /*   if (result.success()) {
            Messages.showInfoMessage(project, "Fetched branch " + branch + " from bundle " + bundlePath, "Success");
            repository.update();  // 更新本地 Git 仓库状态
        } else {
            Messages.showErrorDialog(project, "Failed to fetch from bundle: " + result.getErrorOutputAsJoinedString(), "Error");
        }*/
        return runSuccessNum.get();
    }


    public static Project getActiveProject() {
        Project[] projects = ProjectManager.getInstance().getOpenProjects();
        if (projects.length > 0) {
            return projects[0]; // 返回第一个打开的项目
        }
        return null; // 如果没有打开的项目则返回 null
    }

    public static void showMessage(String title, String content, NotificationType type) {
        Notifications.Bus.notify(new Notification("Print", title,
                content, type), getActiveProject());
    }

    public static void createNewTab(ToolWindow toolWindow, Project project) {
        // 创建一个新的标签
        JPanel newTabPanel = new JPanel();
        JTextArea textArea = new JTextArea(50, 200); // 用于显示命令结果
        newTabPanel.add(new JScrollPane(textArea));
        //JediTermWidget()
        // 在新的标签上执行命令
        executeCommand("cmd.exe dir", textArea);

        ContentFactory contentFactory = ContentFactory.getInstance();
        Content content = contentFactory.createContent(newTabPanel, "执行命令", false);
        toolWindow.getContentManager().addContent(content);
    }

    public static void executeCommand(String command, JTextArea outputArea) {
        try {
            // 执行命令并读取结果
            Process process = Runtime.getRuntime().exec(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                outputArea.append(line + "\n");
            }
            reader.close();

            // 获取命令的返回值
            int exitCode = process.waitFor();
            outputArea.append("Exit code: " + exitCode);
        } catch (Exception ex) {
            outputArea.append("Error executing command: " + ex.getMessage());
        }
    }

    /**
     * getNewBundleFileByPath 获取path目录下最新的bundle文件路径
     * @author huhaoran
     * @date 2024/9/2
     *
     * @param path java.lang.String
     * @return java.lang.String
     */
    public static String getNewBundleFileByPath(String path){
      // 获取path目录下创建事件最新的bundle文件
        File file = new File(path);
        if(file.exists() && file.isDirectory()){
            File[] files = file.listFiles();
            // 过滤掉非bundle文件
            files = Arrays.stream(files).filter(f -> f.getName().endsWith(".bundle")).toArray(File[]::new);
            if(files != null && files.length > 0){
                Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
                return files[0].getAbsolutePath();
            }
        }
        return "";
    }
}
